#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cJSON.h"

// 服务器IP地址宏定义
#define SERVER_IP "127.0.0.1"
// 服务器端口号宏定义，需与服务器端定义的一致
#define SERVER_PORT 6666
// 发送缓冲区大小宏定义
#define MAX_SEND_BUFFER_SIZE 1024
// 接收缓冲区大小宏定义
#define MAX_RECEIVE_BUFFER_SIZE 1024
// 用户名最大长度宏定义，需与服务器端定义的一致
#define USERNAME_MAX_LENGTH 50
// 密码最大长度宏定义，需与服务器端定义的一致
#define PASSWORD_MAX_LENGTH 50

// JSON中操作类型字段名宏定义
#define JSON_TYPE_FIELD "type"

// JSON中用户名字段名宏定义
#define JSON_USERNAME_FIELD "username"

// JSON中密码字段名宏定义
#define JSON_PASSWORD_FIELD "password"

// JSON中旧密码字段名宏定义
#define JSON_OLD_PASSWORD_FIELD "oldPassword"

// JSON中新密码字段名宏定义
#define JSON_NEW_PASSWORD_FIELD "newPassword"


// 定义操作类型枚举，与服务器端保持一致
enum OperationType {
    REGISTER_USER = 0,
    LOGIN,
    CHANGE_PASSWORD,
    EXIT
};

int main() {
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        perror("创建套接字失败");
        return -1;
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
    serverAddr.sin_port = htons(SERVER_PORT);
	
	int ret = 0;
	ret = connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    if (ret == -1) 
	{
        perror("连接服务器失败");
        close(clientSocket);
        return -1;
    }

    char sendBuffer[MAX_SEND_BUFFER_SIZE];
    char receiveBuffer[MAX_RECEIVE_BUFFER_SIZE];

    while (1) {
        printf("\t\t\t----------------------------\t\t\t\n");
        printf("\t\t\t-------1. 注    册----------\t\t\t\n");
        printf("\t\t\t-------2. 登    录----------\t\t\t\n");
        printf("\t\t\t-------3. 修改密码----------\t\t\t\n");
        printf("\t\t\t-------4. 退    出----------\t\t\t\n");
        printf("\t\t\t----------------------------\t\t\t\n");

        printf("please input your choice\n");
        int choice;
        scanf("%d", &choice);

        switch (choice) 
		{
            case REGISTER_USER:
            {
                char username[USERNAME_MAX_LENGTH];
                char password[PASSWORD_MAX_LENGTH];
                printf("请输入用户名\n");
                scanf("%s", username);
                printf("请输入密码\n");
                scanf("%s", password);

                // 创建JSON对象
                cJSON *json = cJSON_CreateObject();
                cJSON_AddItemToObject(json, JSON_TYPE_FIELD, cJSON_CreateNumber(REGISTER_USER));
                cJSON_AddItemToObject(json, "username", cJSON_CreateString(username));
                cJSON_AddItemToObject(json, "password", cJSON_CreateString(password));

                // 将JSON对象转换为字符串并发送
                char *json_str = NULL;
				json_str = cJSON_Print(json);
				
				puts(json_str);
                if (json_str == NULL) {
                    perror("JSON转换字符串失败");
                    cJSON_Delete(json);
                    continue;
                }
                strcpy(sendBuffer, json_str);
                free(json_str);

                ret = send(clientSocket, sendBuffer, strlen(sendBuffer), 0);
                if (ret == -1) {
                    perror("发送注册信息失败");
                    cJSON_Delete(json);
                    break;
                }
				printf("%s",sendBuffer);
                
				cJSON_Delete(json);

                // 接收服务器响应
                memset(receiveBuffer, 0, MAX_RECEIVE_BUFFER_SIZE);
                int recvRet = recv(clientSocket, receiveBuffer, MAX_RECEIVE_BUFFER_SIZE - 1, 0);
                if (recvRet == -1) {
                    perror("接收服务器注册响应失败");
                    break;
                }
                printf("服务器响应：%s\n", receiveBuffer);
            }
                break;
            case LOGIN:
            {
                char username[USERNAME_MAX_LENGTH];
                char password[PASSWORD_MAX_LENGTH];
                printf("请输入用户名\n");
                scanf("%s", username);
                printf("请输入密码\n");
                scanf("%s", password);

                cJSON *json = cJSON_CreateObject();
                cJSON_AddItemToObject(json, JSON_TYPE_FIELD, cJSON_CreateNumber(LOGIN));
                cJSON_AddItemToObject(json, JSON_USERNAME_FIELD, cJSON_CreateString(username));
                cJSON_AddItemToObject(json, JSON_PASSWORD_FIELD, cJSON_CreateString(password));

                char *json_str = cJSON_Print(json);
                if (json_str == NULL) {
                    perror("JSON转换字符串失败");
                    cJSON_Delete(json);
                    continue;
                }
                strcpy(sendBuffer, json_str);
                free(json_str);

                int sendRet = send(clientSocket, sendBuffer, strlen(sendBuffer), 0);
                if (sendRet == -1) {
                    perror("发送登录信息失败");
                    cJSON_Delete(json);
                    break;
                }
                cJSON_Delete(json);

                // 接收服务器响应
                memset(receiveBuffer, 0, MAX_RECEIVE_BUFFER_SIZE);
                int recvRet = recv(clientSocket, receiveBuffer, MAX_RECEIVE_BUFFER_SIZE - 1, 0);
                if (recvRet == -1) {
                    perror("接收服务器登录响应失败");
                    break;
                }
                printf("服务器响应：%s\n", receiveBuffer);
            }
                break;
            case CHANGE_PASSWORD:
            {
                char username[USERNAME_MAX_LENGTH];
                char oldPassword[PASSWORD_MAX_LENGTH];
                char newPassword[PASSWORD_MAX_LENGTH];
                printf("请输入用户名\n");
                scanf("%s", username);
                printf("请输入旧密码\n");
                scanf("%s", oldPassword);
                printf("请输入新密码\n");
                scanf("%s", newPassword);

                cJSON *json = cJSON_CreateObject();
                cJSON_AddItemToObject(json, JSON_TYPE_FIELD, cJSON_CreateNumber(CHANGE_PASSWORD));
                cJSON_AddItemToObject(json, JSON_USERNAME_FIELD, cJSON_CreateString(username));
                cJSON_AddItemToObject(json, JSON_OLD_PASSWORD_FIELD, cJSON_CreateString(oldPassword));
                cJSON_AddItemToObject(json, JSON_NEW_PASSWORD_FIELD, cJSON_CreateString(newPassword));

                char *json_str = cJSON_Print(json);
                if (json_str == NULL) {
                    perror("JSON转换字符串失败");
                    cJSON_Delete(json);
                    continue;
                }
                strcpy(sendBuffer, json_str);
                free(json_str);

                int sendRet = send(clientSocket, sendBuffer, strlen(sendBuffer), 0);
                if (sendRet == -1) {
                    perror("发送修改密码信息失败");
                    cJSON_Delete(json);
                    break;
                }
                cJSON_Delete(json);

                // 接收服务器响应
                memset(receiveBuffer, 0, MAX_RECEIVE_BUFFER_SIZE);
                int recvRet = recv(clientSocket, receiveBuffer, MAX_RECEIVE_BUFFER_SIZE - 1, 0);
                if (recvRet == -1) {
                    perror("接收服务器修改密码响应失败");
                    break;
                }
                printf("服务器响应：%s\n", receiveBuffer);
            }
                break;
            case EXIT:
                close(clientSocket);
                return 0;
            default:
                printf("选择不合理");
                continue;
        }
    }

    close(clientSocket);
    return 0;
}